package tv

import (
    "regexp"
    "strconv"
    "strings"
)

type Episode struct {
    Number int
    Title string
    season int
}

type Season struct {
    Number int
    Episodes []Episode
}

type Show struct {
    Title string
    Seasons []Season
}

func NewShow (data string) *Show {
    return &Show {
        Seasons : parseSeasons(data),
        Title : parseShowTitle(data),
    }
}

// Private methods
func parseShowTitle (html string) string {
    tvShowRegex, _ := regexp.Compile("<h1>[ 0-9A-Za-z]+</h1>")
    tvShow := tvShowRegex.FindString(html)
    if len(tvShow) > 19 {
        return tvShow[4:len(tvShow) - 19]
    } 
    return ""
}

func parseSeasons (html string) (seasons []Season) {
    episodesRegex, _ := regexp.Compile("<li class=\"episode\">[\x00-\x7F]+?</li>")
    rawEpisodes := episodesRegex.FindAllString(html, -1)

    episodes := parseEpisodes(rawEpisodes)

    availableSeasons := []int { }

    seasons = make( []Season, 0 )
    for _, episode := range episodes {
        if hasSeason(availableSeasons, episode.season) == false {
            seasons = append(seasons, makeSeason(episode.season, episodes))
            availableSeasons = append(availableSeasons, episode.season)
        }
    }
    return
}

func parseEpisodes (rawData []string) (episodes []Episode) {
    episodes = make([]Episode, 0)
    for _, ep := range rawData {
        episodes = append( episodes, makeEpisode(ep) )
    }
    return
}

func hasSeason (seasons []int, season int) bool {
    for _, num := range seasons {
        if num == season {
            return true
        }
    }
    return false
}

func makeSeason (seasonNumber int, episodes []Episode) (season Season) {
    season = Season { }
    season.Number = seasonNumber

    for _, ep := range episodes {
        if ep.season == seasonNumber {
            season.Episodes = append(season.Episodes, ep)
        }
    }
    return
}

func makeEpisode (html string) (episode Episode) {
    episode = Episode { } 
    episode.parseTitle(html)
    episode.parseNumber(html)
    episode.parseSeason(html)
    return
}

func (e *Episode) parseTitle (html string) {
    titleRegex, _ := regexp.Compile("<a class=\"title\" href=[\x00-\x7f]+</a>")
    rawTitle := titleRegex.FindString(html)
    index := strings.Index(rawTitle, ">")
    e.Title = strings.Replace(rawTitle[index+1:], "</a>", "", -1)
}

func (e *Episode) parseNumber (html string) {
    numberRegex, _ := regexp.Compile("<dt>Episode</dt>[ \n\r\t\v\f]+<dd>[0-9]+")
    rawNumber := numberRegex.FindString(html)
    index := strings.LastIndex(rawNumber, ">")
    number, _ := strconv.ParseInt(rawNumber[index+1:], 10, 0)
    e.Number = int(number)
}

func (e *Episode) parseSeason (html string) {
    seasonRegex, _ := regexp.Compile("<dt>Season</dt>[ \n\r\t\v\f]+<dd>[0-9]+")
    rawSeason := seasonRegex.FindString(html)
    index := strings.LastIndex(rawSeason, ">")
    season, _ := strconv.ParseInt(rawSeason[index+1:], 10, 0)
    e.season = int(season)
}

